iT邦幫忙

2023 iThome 鐵人賽

DAY 9
0

遞迴的特徵是函式透過不斷呼叫自己,使問題變得越來越小,直到達到base condition停止,而解決問題。他常被用在divide and conquer, greedy algorithm 和 dynamic programming裡。在遞迴發生時,會將小問題存在stack memory(stack先進後出的資料結構,忘記的話可以回去複習一下),看下面這個例子可能會比較清楚,導致其在記憶體的使用上,比iteration的方法不論在時間和空間上都來得沒效率:

# 在這個例子裡,其時間複雜度O(n^2),空間複雜度O(n)
def Fab(n):
    #base condition:這個超級重要,沒有它遞迴會無限循環 
    if n in [0,1]:
        return num
    # 這裡把問題變成小問題來看
    else:
        return Fab(n-1)+Fab(n-2)
Fab(3)

Fab(3)=Fab(2)+Fab(1)
Fab(2)=Fab(1)+Fab(0)
Fab(1)=1
Fab(0)=0
https://ithelp.ithome.com.tw/upload/images/20230919/20162172tFpCrxBZIu.png
在這個例子裡,資料要在記憶體一直堆疊到base condition Fab(0)=0 and Fab(1)=1,才開始返回計算結果,故空間複雜度O(n)。而每一次函式都會呼叫自己兩次,因此會形成一個指數級的遞迴樹,故時間複雜度O(n^2)。

下面我們再看幾個例子:

# 題目是想知道一個數字的數字元總和是多少
# 時間複雜度: O(logn),空間複雜度: O(logn)
def digitsum(n):
    if n==0:
        return 0
    else:
        return n%10+digitsum(n//10)
    
print(digitsum(106))
>> 7
#算最大公因數,b<a
時間複雜度:O(loga),空間複雜度:O(loga)
def gcd(a,b):
    if a<0:
        a=-a
    if b<0:
        b=-b
    if b==0:
        return a
    else:
        return gcd(b,a%b)
print(gcd(30,5))
>> 5

總而言之,有的時候有些程式用iteration的方式可能不是那麼容易被想到,這時候可以用遞迴的方式來處理這些問題,但因為遞迴使用更多的記憶體還有時間,如果時間和記憶體空間非常重要的時候,盡量避免使用遞迴。

參考資料:
本文主要為udemy課程: The Complete Data Structures and Algorithms Course in Python的學習筆記,有興趣的人可以自己上去看看。


上一篇
Queue (佇列)
下一篇
Tree (樹) 與 Binary Tree-1 (二元樹-1)
系列文
用python學習資料結構與演算法 學習筆記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言